from django.shortcuts import render
from django.views import View
from apps.users.models import User
from django import http
import json
import re, logging
from django.contrib.auth import login, authenticate, logout
from django_redis import get_redis_connection
from md_shop.utils.views import LoginRequiredJsonMixin

#设置日志输出
logger = logging.getLogger('django')
# Create your views here.

class EmailView(View):
    '''定义保存邮箱'''
    def put(self, request):
        '''实现添加邮箱的逻辑'''
        #首先从请求体中拿到email
        json_dict = json.loads(request.body.decode())
        email = json_dict.get('email')

        #拿到参数后校验参数
        if not email:
            return http.JsonResponse({'code':400,
                                      'errmsg':'email为空'})
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return http.JsonResponse({'code':400,
                                      'errmsg':'email不符合要求'})
        #写入数据库
        try:
            request.user.email = email
            request.user.save()
        except Exception as e:
            logger.error(e)
            return  http.JsonResponse({'code':400,
                                       'errmsg':'数据库写入错误'})
        #导入发邮件方法
        from celery_tasks.email.tasks import send_verify_email
        # 调用发送的函数:
        verify_url = request.user.generate_verify_email_url()
        send_verify_email(email, verify_url)



        return http.JsonResponse({'code':0,
                                  'errmsg':'保存成功'})


#邮箱后端验证逻辑
class VerifyEmailView(View):
    def put(self, request):
        '''实现用户的邮箱验证'''
        #将token拿出来
        token = request.GET.get('token')
        #判断有没有token
        if not token:
            return http.JsonResponse({'code':0,
                                      'errmsg':'缺少token'})
        #代码执行到此说明拿到token进行解密演证
        user = User.cleck_verify_email_url(token)

        #判断用户是否存在
        if not user:
            return http.JsonResponse({'code': 400,
                                      'errmsg':'用户不存在'})
        #修改用户的email_action
        try:
            user.email_active = True
            user.save()
        except Exception as e:
            logger.error(e)

            return http.JsonResponse({'code':400,
                                      'errmsg':'邮箱解密失败'})
        #到此执行成功
        return http.JsonResponse({'code':0,
                                  'errmsg':'ok'})





class UsernameCountView(View):
    '''判断用户名是否注册'''
    def get(self, request, username):

        try:
            count = User.objects.filter(username=username).count()
        except Exception as e:
            return http.JsonResponse({'code':400,
                                 'errmsg':'访问数据库失败'})

        return http.JsonResponse({'code': 0,
                             'errmsg': 'ok',
                             'count':count})

class UserPhoneView(View):
    '''判断用户手机号
    /mobiles/手机号/count/'
    '''
    def get(self, request, phone):
        try:
            count = User.objects.filter(mobile=phone).count()
        except Exception as e:
            return http.JsonResponse({'code':400,
                                 'errmsg':'访问数据库失败'})
        return http.JsonResponse({'code': 0,
                             'errmsg': 'ok',
                             'count':count})

class UserRegister(View):
    '''用户注册'''
    def post(self, request):
        #拿到用户注册的信息
        json_dict = json.loads(request.body.decode())
        username = json_dict.get('username')
        password = json_dict.get('password')
        password2 = json_dict.get('password2')
        allow = json_dict.get('allow')
        moblie = json_dict.get('mobile')
        code_clent = json_dict.get('sms_code')

        #从redis拿到用户的验证码
        #创建链接对象
        #redis_count = get_redis_connection('verify_code')
        #用链接对象查询
        #redis_count_server = redis_count.get('img_%s' % uuid)

        #校验信息
        if not all([username, password, allow, moblie]):
            return http.JsonResponse({'code':400,
                                      'errmsg':'缺少必要参数'})
        if not re.match(r'^[a-zA-Z]{5,20}$', username):
            return http.JsonResponse({'code':400,
                                      'errmsg':'username格式有误'})
        if not re.match(r'^[0-9a-zA-Z]{8,20}$', password):
            return http.JsonResponse({'code':400,
                                      'errmsg':'password不符和规定'})
        if password != password2:
            return http.JsonResponse({'code':400,
                                      'errmsg':'两次密码输入错误'})
        if not re.match(r'^1[3-9]\d{9}$', moblie):
            return http.JsonResponse({'code':400,
                                 'errmsg':'moblie格式有误'})
        if allow != True:
            return http.JsonResponse({'code':400,
                                      'errmsg':'未同意协议'})
        #查询redis中的短信验证码
        redis_count = get_redis_connection('verify_code')
        sms_code = redis_count.get('sms_%s'% moblie)
        if code_clent != sms_code.decode():
            return http.JsonResponse({'code':400,
                                    'errmsg':'请输入正确的验证码'})
        #插入数据库
        try:
            user = User.objects.create_user(username=username,
                                     password=password,
                                     mobile=moblie)
        except Exception as e:
            logger.error(e)
            print(e)
            return http.JsonResponse({'code':400, 'errmsg': '注册失败'})


        login(request, user)

        #return http.JsonResponse({'code':0,
        #                          'errmsg':'注册成功'})
        #创建Response对象
        Response = http.JsonResponse({'code':0,
                                      'errmsg':'注册成功'})
        #设置scookie
        Response.set_cookie('username', user.username, max_age=3600 * 24 * 14)
        #响应结果
        return Response


#用户登录接口
class LoginView(View):
    def post(self, request):
        '''实现用户登陆'''
        #拿到用户的参数
        request_dict = json.loads(request.body.decode())
        #用户名
        userormobile = request_dict.get('username')
        password = request_dict.get('password')
        remembered = request_dict.get('remembered')
        #排除非法的username@password
        #if not re.match('^[a-zA-Z]{5,20}$', username):
        #    return http.JsonResponse({'code':400,
        #                              'errmsg':'请输入正确的用户名'})
        if not re.match('^[0-9a-zA-Z]{8,20}$', password):
            return http.JsonResponse({'code':400,
                                      'errmsg':'请输入正确的密码'})
        #由于authenticate方法默认是查username,但是还有一种是用手机号登录
        if re.match('^[a-zA-Z]{5,20}$', userormobile):
            User.USERNAME_FIELD = 'username'
        else:
            User.USERNAME_FIELD = 'mobile'
        #查询数据库
        user = authenticate(username=userormobile, password=password)

        if user is None:
            return http.JsonResponse({'code':400,
                                      'errmsg':'用户名或密码错误'})
        #状态保持
        login(request, user)
        if remembered != True:
            #设置session立即失效
            request.session.set_expiry(0)
        else:
            #设置session两周
            request.session.set_expiry(None)
        #返回json
        #return http.JsonResponse({'code':0,
        #                          'errmsg':'登录成功'})

        # 创建Response对象
        Response = http.JsonResponse({'code': 0,
                                          'errmsg': '注册成功'})
        # 设置scookie
        Response.set_cookie('username', user.username, max_age=3600 * 24 * 14)
        # 响应结果
        return Response


class LogoutView(View):
    def delete(self, request):
        '''实现用户退出登录'''
        #清里session
        logout(request)

        #清里cookies
        #创建Response对象
        Response = http.JsonResponse({'code':0,
                                      'errmsg':'ok'})
        #用Response对象清除cookies
        Response.delete_cookie('username')
        #响应
        return Response


class UserInfoView(LoginRequiredJsonMixin, View):
    def get(self, request):
        '''判断用户是否登录'''
        #定义返回的字典
        dict_data = {'code':0,
                     'errmsg':'ok',
                     'info_data':{
                         'username':request.user.username,   #因为在判断了用户是否登陆时就把数据库的用户对象添加到了request中
                         'mobile':request.user.mobile,
                         'email':request.user.email,
                         'email_active':request.user.email_active
                                 }
                     }
        return http.JsonResponse(dict_data)